使用STM32的GPIO模拟I2C通信:从原理到实现

您所在的位置:网站首页 stm32 i2c从设备 使用STM32的GPIO模拟I2C通信:从原理到实现

使用STM32的GPIO模拟I2C通信:从原理到实现

2024-07-09 05:51| 来源: 网络整理| 查看: 265

#include "stm32f4xx_hal.h"

// GPIO定义#define SDA_GPIO_PORT GPIOA#define SDA_PIN GPIO_PIN_0

#define SCL_GPIO_PORT GPIOA#define SCL_PIN GPIO_PIN_1

// 模拟I2C句柄定义typedef struct { GPIO_TypeDef *SDA_GPIO_Port; uint16_t SDA_Pin; GPIO_TypeDef *SCL_GPIO_Port; uint16_t SCL_Pin;} SimulatedI2C_HandleTypeDef;

// 函数声明void SimulatedI2C_Init(SimulatedI2C_HandleTypeDef *hi2c);void SimulatedI2C_Write(SimulatedI2C_HandleTypeDef *hi2c, uint8_t dev_addr, uint8_t *data, uint16_t size);void SimulatedI2C_Read(SimulatedI2C_HandleTypeDef *hi2c, uint8_t dev_addr, uint8_t *data, uint16_t size);

// 延迟函数void I2C_Delay(void) {    // 根据需要添加延迟,也可以用HAL库的HAL_Delay();   for (int i = 0; i < 100; i++);}

// 启动条件void I2C_Start(SimulatedI2C_HandleTypeDef *hi2c) { HAL_GPIO_WritePin(hi2c->SDA_GPIO_Port, hi2c->SDA_Pin, GPIO_PIN_SET); HAL_GPIO_WritePin(hi2c->SCL_GPIO_Port, hi2c->SCL_Pin, GPIO_PIN_SET); I2C_Delay(); HAL_GPIO_WritePin(hi2c->SDA_GPIO_Port, hi2c->SDA_Pin, GPIO_PIN_RESET); I2C_Delay(); HAL_GPIO_WritePin(hi2c->SCL_GPIO_Port, hi2c->SCL_Pin, GPIO_PIN_RESET); I2C_Delay();}

// 停止条件void I2C_Stop(SimulatedI2C_HandleTypeDef *hi2c) { HAL_GPIO_WritePin(hi2c->SDA_GPIO_Port, hi2c->SDA_Pin, GPIO_PIN_RESET); HAL_GPIO_WritePin(hi2c->SCL_GPIO_Port, hi2c->SCL_Pin, GPIO_PIN_SET); I2C_Delay(); HAL_GPIO_WritePin(hi2c->SDA_GPIO_Port, hi2c->SDA_Pin, GPIO_PIN_SET); I2C_Delay();}

// 写入单个字节void I2C_WriteByte(SimulatedI2C_HandleTypeDef *hi2c, uint8_t byte) { for (int8_t i = 7; i >= 0; i--) { if (byte & (1 SDA_GPIO_Port, hi2c->SDA_Pin, GPIO_PIN_SET); } else { HAL_GPIO_WritePin(hi2c->SDA_GPIO_Port, hi2c->SDA_Pin, GPIO_PIN_RESET); } I2C_Delay(); HAL_GPIO_WritePin(hi2c->SCL_GPIO_Port, hi2c->SCL_Pin, GPIO_PIN_SET); I2C_Delay(); HAL_GPIO_WritePin(hi2c->SCL_GPIO_Port, hi2c->SCL_Pin, GPIO_PIN_RESET); I2C_Delay(); }}

// 读取单个字节uint8_t I2C_ReadByte(SimulatedI2C_HandleTypeDef *hi2c) { uint8_t byte = 0; for (int8_t i = 7; i >= 0; i--) { HAL_GPIO_WritePin(hi2c->SCL_GPIO_Port, hi2c->SCL_Pin, GPIO_PIN_SET); I2C_Delay(); if (HAL_GPIO_ReadPin(hi2c->SDA_GPIO_Port, hi2c->SDA_Pin)) { byte |= (1 SCL_GPIO_Port, hi2c->SCL_Pin, GPIO_PIN_RESET); I2C_Delay(); } return byte;}

// 模拟I2C初始化void SimulatedI2C_Init(SimulatedI2C_HandleTypeDef *hi2c) { GPIO_InitTypeDef GPIO_InitStruct = {0};

// 初始化SDA引脚 GPIO_InitStruct.Pin = hi2c->SDA_Pin; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_OD; GPIO_InitStruct.Pull = GPIO_PULLUP; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; HAL_GPIO_Init(hi2c->SDA_GPIO_Port, &GPIO_InitStruct);

// 初始化SCL引脚 GPIO_InitStruct.Pin = hi2c->SCL_Pin; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_OD; GPIO_InitStruct.Pull = GPIO_PULLUP; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; HAL_GPIO_Init(hi2c->SCL_GPIO_Port, &GPIO_InitStruct);}

// 向设备写入数据void SimulatedI2C_Write(SimulatedI2C_HandleTypeDef *hi2c, uint8_t dev_addr, uint8_t *data, uint16_t size) { // 发送起始条件 I2C_Start(hi2c);

// 发送设备地址和写入位 I2C_WriteByte(hi2c, dev_addr



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3